# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import fields, models, api, tools

class DictPartOfSpeech(models.Model):
    _description = 'part_of_speech'
    _name = "dict.part_of_speech"
    _order = "id"

    code = fields.Char(index=True)
    name = fields.Char(index=True)

class DictRawWord(models.Model):
    _description = 'Dict Raw Word'
    _name = "dict.raw_word"
    _order = "name"

    name = fields.Char(index=True, required=True)
    root = fields.Char(index=True )
    extra = fields.Char()
    first_letter = fields.Char( compute='_compute_name', store=True )

    @api.depends('name')
    def _compute_name(self):
        for rec in self:
            rec.first_letter = rec.name[0:1]

    word_ids = fields.One2many('dict.word', 'raw_word_id')
    word_id = fields.Many2one('dict.word', compute='_compute_word_id')
    learning_level = fields.Integer( compute='_compute_word_id')
    part_of_speech_ids = fields.Many2many('dict.part_of_speech', compute='_compute_part_of_speech')
    part_of_speech = fields.Char(compute='_compute_part_of_speech', store=True)

    meaning_ids = fields.One2many('dict.meaning', 'raw_word_id')
    meanings_cn = fields.Char(compute='_compute_meanings_cn' )
    # example_ids = fields.One2many('dict.example', 'raw_word_id')

    # learning_ids_for_all = fields.One2many('dict.learning', 'raw_word_id' )
    # learning_ids = fields.One2many('dict.learning', compute='_compute_learning_id' )

    @api.depends('word_ids')
    def _compute_word_id(self):
        for rec in self:
            if len(rec.word_ids) == 1:
                rec.word_id = rec.word_ids
                rec.learning_level = rec.word_id.learning_level
            else:
                rec.word_id = self.env['dict.word']
                rec.learning_level = 0

    @api.depends('word_ids')
    def _compute_part_of_speech(self):
        for rec in self:
            part_of_speech_ids = rec.word_ids.mapped('part_of_speech_ids')
            rec.part_of_speech_ids = part_of_speech_ids
            rec.part_of_speech = ', '.join( part_of_speech_ids.mapped('code') )

    @api.depends('meaning_ids' )
    def _compute_meanings_cn(self):
        def fn(mean):
            number = mean.number
            meaning = mean.meaning_cn
            no = number and str(number) + ':'  or ''
            return no + meaning
        
        for rec in self:
            ms = [ fn(mean) for mean in rec.meaning_ids]
            rec.meanings_cn = '; '.join(ms)

    # @api.depends('learning_ids_for_all')
    # def _compute_learning_id(self):
    #     for rec in self:
    #         rec.learning_ids = rec.learning_ids_for_all.filtered(
    #             lambda r: r.user_id == self.env.user)


class DictWord(models.Model):
    _description = 'Dict Word'
    _name = "dict.word"
    _order = "word, number"

    raw_word_id = fields.Many2one('dict.raw_word', index=True, required=True )
    number = fields.Integer(default=0, index=True, required=True)
    name = fields.Char(compute='_compute_name', store=True)

    word = fields.Char( related='raw_word_id.name', index=True, store=True )
    root = fields.Char( related='raw_word_id.root', index=True, store=True )
    group_word_ids = fields.Many2many('dict.word', compute='_compute_group_word_ids' )
    first_letter = fields.Char( related='raw_word_id.first_letter' )
    extra = fields.Char()

    is_key = fields.Boolean(default=False)
    is_check = fields.Boolean(default=False)


    @api.depends('word', 'number')
    def _compute_name(self):
        for rec in self:
            if not rec.word:
                continue
            names = [rec.word]
            if rec.number:
                names.append( str(rec.number) )
            rec.name = ' '.join(names)

    part_of_speech_ids = fields.Many2many('dict.part_of_speech')
    part_of_speech = fields.Char(compute='_compute_part_of_speech', store=True)

    @api.depends('part_of_speech_ids')
    def _compute_part_of_speech(self):
        for rec in self:
            codes = rec.part_of_speech_ids.mapped('code')
            rec.part_of_speech = ', '.join( codes )

    meaning_ids = fields.One2many('dict.meaning', 'word_id')
    meanings_cn = fields.Char(compute='_compute_meanings_cn' )

    @api.depends('meaning_ids', 'meaning_ids.number', 'meaning_ids.meaning_cn' )
    def _compute_meanings_cn(self):
        def fn(mean):
            number = mean.number
            meaning = mean.meaning_cn
            no = number and str(number) + ':'  or ''
            return no + meaning
        
        for rec in self:
            ms = [ fn(mean) for mean in rec.meaning_ids]
            rec.meanings_cn = '; '.join(ms)


    example_ids = fields.One2many('dict.example', compute='_compute_example_ids')

    @api.depends('meaning_ids')
    def _compute_example_ids(self):
        for rec in self:
            rec.example_ids = rec.meaning_ids.mapped('example_ids')

    learning_ids = fields.One2many('dict.learning', 'word_id' )
    learning_id = fields.Many2one('dict.learning', compute='_compute_learning_id' )
    learning_level = fields.Integer(default=0, compute='_compute_learning_id')

    @api.depends('learning_ids')
    def _compute_learning_id(self):
        for rec in self:
            learning = rec.learning_ids.filtered(lambda r: r.user_id == self.env.user)
            learning = learning and learning[0] or learning
            rec.learning_id = learning
            level = learning and learning.level or 0
            if not level:
                user_admin = self.env['ir.model.data'].xmlid_to_res_id('base.user_admin')
                learning = rec.learning_ids.filtered(lambda r: r.user_id.id == user_admin)
                level = learning and learning.level or 0

            rec.learning_level = level

    @api.depends('root')
    def _compute_group_word_ids(self):
        for rec in self:
            if rec.root:
                rec.group_word_ids = self.search([['root','=',rec.root],['id','!=', rec.id]])
            else:
                rec.group_word_ids = self.env['dict.word']


    @api.model
    def to_learn(self, vals_list):
        if not vals_list:
            vals_list = []

        learning_obj = self.env['dict.learning']
        learning_ids = self.env['dict.learning']

        for vals in vals_list:
            learning_id = vals.get('learning_id')
            del vals['learning_id']

            if learning_id:
                learning = learning_obj.browse(learning_id)
                del vals['word_id']
                learning.write(vals)
            else:
                vals.update({'user_id': self.env.user.id })
                learning = learning_obj.create(vals)
            
            learning_ids |= learning 
        
        return learning_ids.ids

class DictMeaning(models.Model):
    _description = 'Dict Meaning'
    _name = "dict.meaning"
    _order = "word_id, number"

    word_id = fields.Many2one('dict.word', 'word_id', index=True, required=True )
    raw_word_id = fields.Many2one('dict.raw_word', related='word_id.raw_word_id', store=True )
    word = fields.Char( related='word_id.word' )
    word_name = fields.Char( related='word_id.name' )
    word_number = fields.Integer( related='word_id.number' )
    word_root = fields.Char( related='word_id.root' )
    is_key = fields.Boolean( related='word_id.is_key')
    part_of_speech_ids = fields.Many2many( related='word_id.part_of_speech_ids' )
    part_of_speech = fields.Char( related='word_id.part_of_speech' )

    number = fields.Integer(default=0, index=True)
    name = fields.Char(compute='_compute_name', store=True)
    meaning = fields.Char()
    meaning_cn = fields.Char()
    example_ids = fields.One2many('dict.example', 'meaning_id')

    @api.depends('word_id', 'number')
    def _compute_name(self):
        for rec in self:
            names = [rec.word_id.name]
            if rec.number:
                names.append( str(rec.number) )
            rec.name = ' ,'.join(names)



class DictWordMeaningExample(models.Model):
    _description = 'Dict Example'
    _name = "dict.example"
    _order = "meaning_id, number"

    meaning_id = fields.Many2one('dict.meaning', 'meaning_id', index=True, required=True )
    word_id = fields.Many2one('dict.word', 'word_id', related='meaning_id.word_id' , store=True)
    raw_word_id = fields.Many2one('dict.raw_word', related='meaning_id.raw_word_id', store=True )
    part_of_speech = fields.Char( related='meaning_id.part_of_speech' )
    name = fields.Char(compute='_compute_name', store=True)
    number = fields.Integer(default=0, index=True)
    example = fields.Char()
    example_cn = fields.Char()

    @api.depends('meaning_id', 'number')
    def _compute_name(self):
        for rec in self:
            names = [rec.meaning_id.name]
            if rec.number:
                names.append( str(rec.number) )
            rec.name = ' '.join(names)

